home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The CICA Windows Explosion!
/
The CICA Windows Explosion! - Disc 2.iso
/
programr
/
eckelt01.zip
/
14
/
TSTASH.H
< prev
next >
Wrap
C/C++ Source or Header
|
1995-02-23
|
5KB
|
164 lines
// File from page 592 in "Thinking in C++" by Bruce Eckel
//////////////////////////////////////////////////
// From the compressed package ECKELT01.ZIP 2/21/95
// Copyright (c) Bruce Eckel, 1995
// Source code file from the book "Thinking in C++",
// Prentice Hall, 1995, ISBN: 0-13-917709-4
// All rights reserved EXCEPT as allowed by the following
// statements: You may freely use this file for your own
// work, including modifications and distribution in
// executable form only. You may copy and distribute this
// file, as long as it is only distributed in the complete
// (compressed) package with the other files from this
// book and you do not remove this copyright and notice.
// You may not distribute modified versions of the source
// code in this package. This package may be freely placed
// on bulletin boards, internet nodes, shareware disks and
// product vendor disks. You may not use this file in
// printed media without the express permission of the
// author. Bruce Eckel makes no
// representation about the suitability of this software
// for any purpose. It is provided "as is" without express
// or implied warranty of any kind. The entire risk as to
// the quality and performance of the software is with
// you. Should the software prove defective, you assume
// the cost of all necessary servicing, repair, or
// correction.
// If you think you've found an error, please
// email all modified files with loudly commented changes
// to: eckel@aol.com (please use the same
// address for non-code errors found in the book).
//////////////////////////////////////////////////
//: TSTASH.H -- PSTASH using templates
#ifndef TSTASH_H_
#define TSTASH_H_
#include <stdlib.h>
#include "..\allege.h"
// Should be nested inside tstash; more
// convenient global. You can move it:
enum owns { no = 0, yes = 1, Default };
template<class Type, int chunksize = 20>
class tstash {
int quantity;
int next;
owns own; // Flag
void inflate(int increase = chunksize);
protected:
Type** storage;
public:
tstash(owns Owns = yes);
~tstash();
int Owns() const { return own; }
void Owns(owns newOwns) { own = newOwns; }
int add(Type* element);
int remove(int index, owns d = Default);
Type* operator[](int index);
int count() const { return next; }
friend class tstashIter<Type, chunksize>;
};
template<class Type, int sz = 20>
class tstashIter {
tstash<Type, sz>& ts;
int index;
public:
tstashIter(tstash<Type, sz>& TS)
: ts(TS), index(0) {}
tstashIter(const tstashIter& rv)
: ts(rv.ts), index(rv.index) {}
// Jump interator forward or backward:
void forward(int amount) {
index += amount;
if(index >= ts.next) index = ts.next -1;
}
void backward(int amount) {
index -= amount;
if(index < 0) index = 0;
}
// Return value of ++ and -- to be
// used inside conditionals:
int operator++() {
if(++index >= ts.next) return 0;
return 1;
}
int operator++(int) { return operator++(); }
int operator--() {
if(--index < 0) return 0;
return 1;
}
int operator--(int) { return operator--(); }
operator int() {
return index >= 0 && index < ts.next;
}
Type* operator->() {
Type* t = ts.storage[index];
if(t) return t;
allege(0,"tstashIter::operator->return 0");
return 0; // To allow inlining
}
// Remove the current element:
int remove(owns d = Default){
return ts.remove(index, d);
}
};
template<class Type, int sz>
tstash<Type, sz>::tstash(owns Owns) : own(Owns) {
quantity = 0;
storage = 0;
next = 0;
}
// Destruction of contained objects:
template<class Type, int sz>
tstash<Type, sz>::~tstash() {
if(!storage) return;
if(own == yes)
for(int i = 0; i < count(); i++)
delete storage[i];
free(storage);
}
template<class Type, int sz>
int tstash<Type, sz>::add(Type* element) {
if(next >= quantity)
inflate();
storage[next++] = element;
return(next - 1); // Index number
}
template<class Type, int sz>
int tstash<Type, sz>::remove(int index,owns d){
if(index >= next || index < 0)
return 0;
switch(d) {
case Default:
if(own != yes) break;
case yes:
delete storage[index];
case no:
storage[index] = 0; // Position is empty
}
return 1;
}
template<class Type, int sz> inline
Type* tstash<Type, sz>::operator[](int index) {
// No check in shipping application:
assert(index >= 0 && index < next);
return storage[index];
}
template<class Type, int sz>
void tstash<Type, sz>::inflate(int increase) {
void* v =
realloc(storage, (quantity+increase)*sizeof(Type*));
allegemem(v); // Was it successful?
storage = (Type**)v;
quantity += increase;
}
#endif // TSTASH_H_